<template>
  <div class="home-container">
    <!-- 热门推荐区域 -->
    <div class="hot-recommend-section" v-if="hotRecommendList.length > 0">
      <div class="section-header">
        <div class="header-left">
          <FireOutlined class="section-icon" />
          <h2 class="section-title">🔥 热门推荐</h2>
          <span class="section-subtitle">发现最受欢迎的图片</span>
        </div>
        <div class="header-right">
          <a-button type="link" @click="switchToRanking"> 查看更多 <RightOutlined /> </a-button>
        </div>
      </div>
      <div class="hot-recommend-list">
        <div
          v-for="item in hotRecommendList"
          :key="item.id"
          class="hot-recommend-item"
          @click="showImageDetails(item)"
        >
          <div class="item-image">
            <img
              :src="IMAGE_PREFIX + (item.thumbnailUrl || '')"
              :alt="item.name"
              @error="handleImageError"
            />
            <div class="item-overlay">
              <div class="overlay-content">
                <EyeOutlined />
              </div>
            </div>
            <div class="hot-badge">
              <FireOutlined />
            </div>
          </div>
          <div class="item-info">
            <div class="item-name">{{ item.name }}</div>
            <div class="item-stats">
              <span class="stat-item">
                <HeartOutlined />
                {{ formatCount(item.likeCount) }}
              </span>
              <span class="stat-item">
                <StarOutlined />
                {{ formatCount(item.favoriteCount) }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 筛选和操作区域 -->
    <div class="filter-section">
      <!-- 分类选择 -->
      <div class="filter-row">
        <div class="filter-label">分类</div>
        <div class="filter-content">
          <a-button
            class="filter-button"
            :type="filterParams.category === '' ? 'primary' : 'default'"
            @click="toggleCategory('')"
          >
            全部
          </a-button>
          <a-button
            v-for="category in categories"
            :key="category"
            :type="filterParams.category === category ? 'primary' : 'default'"
            @click="toggleCategory(category)"
            class="filter-button"
          >
            {{ category }}
          </a-button>
        </div>
      </div>

      <!-- 标签选择 -->
      <div class="filter-row">
        <div class="filter-label">标签</div>
        <div class="filter-content">
          <a-button
            v-for="tag in tags"
            :key="tag"
            :type="filterParams.tags.includes(tag) ? 'primary' : 'default'"
            @click="toggleTag(tag)"
            class="filter-button"
          >
            {{ tag }}
          </a-button>
        </div>
      </div>

      <!-- 颜色选择 -->
      <div class="filter-row">
        <span class="filter-label">颜色：</span>
        <div class="filter-content">
          <div class="color-selector">
            <input type="color" v-model="filterParams.color" class="color-input" />
            <div class="color-display">
              <div
                class="color-preview"
                :style="{ backgroundColor: filterParams.color || '#ffffff' }"
              />
              <span>{{ filterParams.color || '请选择颜色' }}</span>
            </div>
            <a-button type="primary" @click="searchByColor" :disabled="!filterParams.color">
              <template #icon><SearchOutlined /></template>
              搜索
            </a-button>
            <span class="color-search-tip">（仅可搜索您空间内的图片）</span>
          </div>
        </div>
      </div>

      <!-- 搜索和操作栏 -->
      <div class="operation-bar">
        <div class="search-area">
          <a-input-search
            v-model:value="filterParams.searchText"
            placeholder="输入关键词搜索图片..."
            style="width: 300px"
            @input="onSearchInput"
            @search="applyFilters"
          />
        </div>
        <div class="action-area">
          <a-space>
            <a-button type="primary" @click="applyFilters">
              <template #icon><SearchOutlined /></template>
              应用筛选
            </a-button>
            <a-button @click="resetFilters">
              <template #icon><ReloadOutlined /></template>
              重置
            </a-button>
          </a-space>
        </div>
      </div>

      <!-- 页面类型切换 -->
      <div class="filter-row page-type-row">
        <div class="filter-content page-type-content">
          <div class="page-type-wrapper">
            <a-radio-group
              v-model:value="pageType"
              @change="handlePageTypeChange"
              class="page-type-selector"
            >
              <a-radio-button value="basic">
                <span class="button-icon">🏠</span>
                <span class="button-text">基础页面</span>
              </a-radio-button>
              <a-radio-button value="featured">
                <span class="button-icon">⭐</span>
                <span class="button-text">精选推荐</span>
              </a-radio-button>
              <a-radio-button value="ranking">
                <span class="button-icon">🔥</span>
                <span class="button-text">热度排行</span>
              </a-radio-button>
            </a-radio-group>

            <!-- 页面类型切换loading指示器 -->
            <!-- <div v-if="loading" class="page-type-loading">
              <a-spin size="small" />
            </div> -->
          </div>
        </div>
      </div>

      <!-- 热度筛选区域 -->
      <div class="filter-row popularity-filter-row" v-if="pageType === 'ranking'">
        <div class="filter-content popularity-filter-content">
          <a-radio-group
            v-model:value="popularityFilter"
            @change="handlePopularityFilterChange"
            class="popularity-filter-selector"
          >
            <a-radio-button value="yesterday">
              <span class="popularity-icon">🔥</span>
              <span class="popularity-text">昨天最热</span>
            </a-radio-button>
            <a-radio-button value="lastWeek">
              <span class="popularity-icon">📈</span>
              <span class="popularity-text">上周最热</span>
            </a-radio-button>
            <a-radio-button value="lastMonth">
              <span class="popularity-icon">📊</span>
              <span class="popularity-text">上月最热</span>
            </a-radio-button>
          </a-radio-group>
        </div>
      </div>
    </div>

    <!-- 工具栏 -->
    <div class="toolbar-section">
      <div class="left">
        <a-space>
          <a-button-group>
            <a-tooltip title="网格视图">
              <a-button
                :type="viewMode === 'grid' ? 'primary' : 'default'"
                @click="handleViewModeChange('grid')"
              >
                <template #icon><AppstoreOutlined /></template>
              </a-button>
            </a-tooltip>
            <a-tooltip title="列表视图">
              <a-button
                :type="viewMode === 'list' ? 'primary' : 'default'"
                @click="handleViewModeChange('list')"
              >
                <template #icon><BarsOutlined /></template>
              </a-button>
            </a-tooltip>
            <a-tooltip title="瀑布流视图">
              <a-button
                :type="viewMode === 'waterfall' ? 'primary' : 'default'"
                @click="handleViewModeChange('waterfall')"
              >
                <template #icon><AppstoreOutlined :rotate="45" /></template>
              </a-button>
            </a-tooltip>
          </a-button-group>
          <a-button :type="isSelectionMode ? 'primary' : 'default'" @click="toggleSelectionMode">
            <template #icon><CheckSquareOutlined /></template>
            {{ isSelectionMode ? '退出选择' : '多选' }}
          </a-button>
          <template v-if="isSelectionMode">
            <a-button type="default" @click="toggleSelectAllOnPage">
              {{
                selectedImages.length === dataList.length && dataList.length > 0
                  ? '取消全选'
                  : '全选本页'
              }}
            </a-button>
            <a-button
              type="primary"
              :disabled="selectedImages.length === 0"
              @click="handleBatchFavorite"
            >
              <template #icon><StarOutlined /></template>
              批量收藏
            </a-button>
            <a-button
              type="primary"
              :disabled="selectedImages.length === 0"
              @click="handleBatchLike"
            >
              <template #icon><HeartOutlined /></template>
              批量点赞
            </a-button>
            <a-button
              type="default"
              :disabled="selectedImages.length === 0"
              @click="handleBatchCancelFavorite"
            >
              <template #icon><StarOutlined /></template>
              批量取消收藏
            </a-button>
            <a-button
              type="default"
              :disabled="selectedImages.length === 0"
              @click="handleBatchCancelLike"
            >
              <template #icon><HeartOutlined /></template>
              批量取消点赞
            </a-button>
          </template>
        </a-space>
      </div>
      <div class="right">
        <a-space>
          <template v-if="isSelectionMode">
            <span class="selection-info">已选择 {{ selectedImages.length }} 项</span>
            <a-button type="primary" :disabled="selectedImages.length === 0" @click="batchDownload">
              <template #icon><DownloadOutlined /></template>
              批量下载
            </a-button>
          </template>

          <a-button @click="refreshCurrentPage">
            <template #icon><SyncOutlined /></template>
            刷新
          </a-button>
          <DownloadProgress
            v-model="showDownloadProgress"
            :tasks="downloadTasks"
            @clear-completed="clearCompletedTasks"
          >
            <a-button>
              <template #icon>
                <DownloadOutlined />
              </template>
              下载进度
              <a-badge
                :count="downloadTasks.length"
                :dot="downloadTasks.length > 0"
                :offset="[8, 0]"
              />
            </a-button>
          </DownloadProgress>
        </a-space>
      </div>
    </div>

    <!-- 图片展示区域 -->
    <div class="content-section">
      <a-spin :spinning="loading" tip="加载中...">
        <!-- 网格视图 -->
        <div v-if="viewMode === 'grid'" class="grid-view">
          <div v-for="item in dataList" :key="item.url" class="grid-item">
            <div
              class="image-card"
              :class="{ 'is-selected': selectedImages.includes(item) }"
              @click="handleImageClick(item)"
            >
              <div class="image-wrapper">
                <img
                  :src="IMAGE_PREFIX + (item.thumbnailUrl || '')"
                  :alt="item.introduction || '暂无描述'"
                  class="image"
                  @error="handleImageError"
                />
                <div class="image-overlay">
                  <div class="overlay-content">
                    <EyeOutlined @click.stop="showImageDetails(item)" />
                  </div>
                </div>
              </div>
              <div class="image-info">
                <div class="image-name" v-html="highlightKeyword(item.name).html"></div>
                <div
                  v-if="
                    filterParams.searchText &&
                    !highlightKeyword(item.name).matched &&
                    item.introduction &&
                    item.introduction.toLowerCase().includes(filterParams.searchText.toLowerCase())
                  "
                  class="image-desc-highlight"
                >
                  <span v-html="highlightKeyword(item.introduction).html"></span>
                  <span class="desc-match-tip">（描述匹配）</span>
                </div>
                <div class="image-meta">
                  <span class="category">{{ item.category }}</span>
                  <span class="size">{{ (Number(item.picSize) / 1024).toFixed(2) }} KB</span>
                </div>
                <div class="image-action-bar">
                  <span class="icon-btn" @click.stop="handleLike(item)">
                    <template v-if="item.liked">
                      <HeartFilled style="color: #f5222d" />
                    </template>
                    <template v-else>
                      <HeartOutlined />
                    </template>
                    {{ formatCount(item.likeCount) }}
                  </span>
                  <span class="icon-btn" @click.stop="handleFavorite(item)">
                    <template v-if="item.favorited">
                      <StarFilled style="color: #faad14" />
                    </template>
                    <template v-else>
                      <StarOutlined />
                    </template>
                    {{ formatCount(item.favoriteCount) }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 瀑布流视图 -->
        <div v-else-if="viewMode === 'waterfall'" class="waterfall-view">
          <div
            v-for="(item, index) in dataList"
            :key="item.url"
            class="waterfall-item"
            :class="{ 'is-selected': selectedImages.includes(item) }"
            :style="{ 'animation-delay': `${index * 0.05}s` }"
            @click="handleImageClick(item)"
          >
            <div class="waterfall-image-wrapper">
              <img
                :src="IMAGE_PREFIX + (item.thumbnailUrl || '')"
                :alt="item.introduction || '暂无描述'"
                class="waterfall-image"
                @error="handleImageError"
                @load="handleImageLoad($event)"
              />
              <div class="image-overlay">
                <div class="overlay-content">
                  <EyeOutlined @click.stop="showImageDetails(item)" />
                </div>
              </div>
            </div>
            <div class="waterfall-info">
              <div class="waterfall-name" v-html="highlightKeyword(item.name).html"></div>
              <div class="waterfall-meta">
                <span class="category">{{ item.category }}</span>
                <span class="size">{{ (Number(item.picSize) / 1024).toFixed(2) }} KB</span>
              </div>
              <div class="waterfall-actions">
                <span class="waterfall-action-btn" @click.stop="handleLike(item)">
                  <template v-if="item.liked">
                    <HeartFilled style="color: #f5222d" />
                  </template>
                  <template v-else>
                    <HeartOutlined />
                  </template>
                  {{ formatCount(item.likeCount) }}
                </span>
                <span class="waterfall-action-btn" @click.stop="handleFavorite(item)">
                  <template v-if="item.favorited">
                    <StarFilled style="color: #faad14" />
                  </template>
                  <template v-else>
                    <StarOutlined />
                  </template>
                  {{ formatCount(item.favoriteCount) }}
                </span>
              </div>
            </div>
          </div>
        </div>

        <!-- 列表视图 -->
        <div v-else-if="viewMode === 'list'" class="list-view">
          <a-table
            :dataSource="dataList"
            :columns="getColumns()"
            :pagination="false"
            :rowKey="rowKeyFn"
            :rowSelection="
              isSelectionMode
                ? {
                    selectedRowKeys: selectedImages.map(img => img.url),
                    onChange: handleTableSelection,
                  }
                : undefined
            "
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.dataIndex === 'thumbnailUrl'">
                <img
                  :src="IMAGE_PREFIX + (record.thumbnailUrl || '')"
                  :alt="record.introduction"
                  class="table-image"
                  @click="showImageDetails(record)"
                />
              </template>
              <template v-else-if="column.dataIndex === 'tags'">
                <a-space wrap>
                  <a-tag v-for="tag in record.tags ? JSON.parse(record.tags) : []" :key="tag">
                    {{ tag }}
                  </a-tag>
                </a-space>
              </template>
              <template v-else-if="column.dataIndex === 'picSize'">
                {{ (Number(record.picSize) / 1024).toFixed(2) }} KB
              </template>
              <template v-else-if="column.dataIndex === 'operation'">
                <a-space>
                  <a-button 
                    type="text" 
                    size="small" 
                    @click.stop="handleLike(record)"
                    class="icon-only-btn"
                  >
                    <template #icon>
                      <HeartFilled v-if="record.liked" style="color: #f5222d" />
                      <HeartOutlined v-else style="color: #8c8c8c" />
                    </template>
                  </a-button>
                  <a-button 
                    type="text" 
                    size="small" 
                    @click.stop="handleFavorite(record)"
                    class="icon-only-btn"
                  >
                    <template #icon>
                      <StarFilled v-if="record.favorited" style="color: #faad14" />
                      <StarOutlined v-else style="color: #8c8c8c" />
                    </template>
                  </a-button>
                </a-space>
              </template>
            </template>
          </a-table>
        </div>

        <!-- 分页器 -->
        <div class="pagination-container">
          <a-pagination
            v-model:current="getPictureListParams.page"
            :total="total"
            :pageSize="getPictureListParams.pageSize"
            :show-total="showTotal"
            show-size-changer
            @change="handlePageChange"
            @showSizeChange="handleSizeChange"
          />
        </div>
      </a-spin>

      <!-- 图片预览 -->
      <a-modal
        v-model:open="detailVisible"
        :footer="null"
        width="80%"
        style="max-width: 1200px"
        @cancel="closeImageDetails"
      >
        <div class="image-detail" v-if="selectedImage">
          <div class="detail-content">
            <!-- 左侧图片展示 -->
            <div class="detail-image">
              <img
                :src="IMAGE_PREFIX + selectedImage.thumbnailUrl"
                :alt="selectedImage.introduction"
              />
            </div>

            <!-- 右侧信息展示 -->
            <div class="detail-info">
              <h3 class="preview-title">图片信息</h3>
              <div class="info-item">
                <span class="info-label">文件名：</span>
                <span class="info-value">{{ selectedImage.name }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">描述：</span>
                <span
                  class="info-value"
                  :class="{ 'empty-text': !selectedImage.introduction }"
                  v-html="highlightKeyword(selectedImage.introduction || '暂无描述').html"
                ></span>
              </div>
              <div class="info-item">
                <span class="info-label">分类：</span>
                <a-tag v-if="selectedImage.category" class="info-tag">{{ selectedImage.category }}</a-tag>
                <span v-else class="empty-text">未分类</span>
              </div>
              <div class="info-item">
                <span class="info-label">标签：</span>
                <div class="info-value">
                  <template v-if="selectedImage.tags">
                    <div class="tags-list">
                      <template v-for="(tag, index) in parseTags(selectedImage.tags)" :key="tag">
                        <template v-if="index < 4">
                          <a-tag class="info-tag">{{ tag }}</a-tag>
                        </template>
                      </template>
                      <a-tooltip
                        v-if="parseTags(selectedImage.tags).length > 4"
                        :title="parseTags(selectedImage.tags).slice(4).join(', ')"
                      >
                        <a-tag class="info-tag">
                          +{{ parseTags(selectedImage.tags).length - 4 }}
                        </a-tag>
                      </a-tooltip>
                    </div>
                  </template>
                  <span v-else class="empty-text">暂无标签</span>
                </div>
              </div>
              <div class="info-item">
                <span class="info-label">大小：</span>
                <span class="info-value">{{ (Number(selectedImage.picSize) / 1024).toFixed(2) }} KB</span>
              </div>
              <div class="info-item">
                <span class="info-label">分辨率：</span>
                <span class="info-value">{{ selectedImage.picWidth }} × {{ selectedImage.picHeight }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">格式：</span>
                <span class="info-value">{{ selectedImage.picFormat?.toUpperCase() || '-' }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">创建时间：</span>
                <span class="info-value" :class="{ 'empty-text': !selectedImage.createTime }">
                  {{
                    selectedImage.createTime ? formatDate(Number(selectedImage.createTime)) : '未知'
                  }}
                </span>
              </div>
              <div class="info-item">
                <span class="info-label">更新时间：</span>
                <span class="info-value" :class="{ 'empty-text': !selectedImage.updateTime }">
                  {{
                    selectedImage.updateTime ? formatDate(Number(selectedImage.updateTime)) : '未知'
                  }}
                </span>
              </div>
              <div class="image-action-bar">
                <span class="icon-btn" @click="handleLike(selectedImage)">
                  <template v-if="selectedImage.liked">
                    <HeartFilled style="color: #f5222d" />
                  </template>
                  <template v-else>
                    <HeartOutlined />
                  </template>
                  {{ formatCount(selectedImage.likeCount) }}
                </span>
                <span class="icon-btn" @click="handleFavorite(selectedImage)">
                  <template v-if="selectedImage.favorited">
                    <StarFilled style="color: #faad14" />
                  </template>
                  <template v-else>
                    <StarOutlined />
                  </template>
                  {{ formatCount(selectedImage.favoriteCount) }}
                </span>
              </div>
              <div class="action-buttons">
                <a-space>
                  <a-button type="primary" @click="downloadImage(selectedImage)">
                    <template #icon><DownloadOutlined /></template>
                    下载图片
                  </a-button>
                  <a-button
                    type="primary"
                    @click="handleAIOutPainting"
                    :loading="aiOutPaintingLoading"
                  >
                    <template #icon><ExperimentOutlined /></template>
                    AI扩图
                  </a-button>
                </a-space>
              </div>
            </div>
          </div>
        </div>
      </a-modal>
    </div>

    <!-- 下载进度显示 -->
    <template v-if="downloadList.length > 0">
      <div class="download-status">
        <div class="download-header">
          <span>下载列表 ({{ downloadList.length }})</span>
          <a-button type="link" size="small" @click="showAllDownloads = !showAllDownloads">
            {{ showAllDownloads ? '收起' : '展开' }}
          </a-button>
        </div>
        <div class="download-list">
          <div v-for="item in displayDownloads" :key="item.id" class="download-item">
            <div class="download-info">
              <span class="filename">{{ item.filename }}</span>
              <a-progress :percent="item.progress" size="small" :status="item.status" />
            </div>
          </div>
        </div>
        <div v-if="remainingDownloads > 0" class="more-downloads">
          <span>还有 {{ remainingDownloads }} 个下载任务...</span>
        </div>
      </div>
    </template>
  </div>
</template>

<script lang="ts" setup>
  import { onMounted, reactive, ref, computed, nextTick, watch, onUnmounted } from 'vue'
import {
  getCategoriesUsingGet1,
  getTagsUsingGet1,
  getPictureListUsingGet1,
  searchByColorUsingGet1,
  batchAddFavoriteUsingPost1,
  likePictureUsingPost1,
  getBatchLikeFavoriteStatusUsingGet,
  batchCancelFavoriteUsingPost1,
  cancelLikePictureUsingPost1,
  searchPictureByKeywordUsingGet,
} from '@/api/tupianguanlijiekou'
import { createPictureOutPaintingTaskUsingPost } from '@/api/aijiekou'
import { message } from 'ant-design-vue'
import { formatDate } from '@/utils/date'
import {
  AppstoreOutlined,
  BarsOutlined,
  DownloadOutlined,
  SyncOutlined,
  EyeOutlined,
  SearchOutlined,
  ReloadOutlined,
  CheckSquareOutlined,
  ExperimentOutlined,
  StarOutlined,
  HeartOutlined,
  StarFilled,
  HeartFilled,
  FireOutlined,
  RightOutlined,
} from '@ant-design/icons-vue'
import { IMAGE_PREFIX } from '@/config/constants'



interface PictureItem {
  id: number
  url: string
  thumbnailUrl: string
  name: string
  introduction: string
  category: string
  tags: string
  picWidth: number
  picHeight: number
  picSize: number
  picFormat: string
  createTime?: string
  updateTime?: string
  editTime?: string
  likeCount?: number
  favoriteCount?: number
  liked?: boolean
  favorited?: boolean
}

interface DownloadTask {
  id: string
  filename: string
  status: '下载中' | '已完成' | '已失败'
  progress: number
}



// 热门推荐数据
const hotRecommendList = ref<PictureItem[]>([])

// 筛选参数
const filterParams = reactive({
  category: '',
  tags: [] as string[],
  searchText: '',
  color: '#ffffff', // 设置默认颜色为白色，避免空字符串错误
})

// 页面类型切换
const pageType = ref<'basic' | 'featured' | 'ranking'>('basic')

  // 热度筛选
  const popularityFilter = ref<'yesterday' | 'lastWeek' | 'lastMonth'>('yesterday')

// 定义请求参数
const getPictureListParams = ref<API.getPictureListUsingGET2Params>({
  page: 1,
  pageSize: 35,
  category: undefined,
  tags: undefined,
  searchText: '',
  type: 'all',
})

// 定义数据
const dataList = ref<PictureItem[]>([])
const total = ref(0)
const loading = ref(false)
const categories = ref<string[]>([])
const tags = ref<string[]>([])
const detailVisible = ref(false)
const selectedImage = ref<PictureItem | null>(null)
const viewMode = ref<'grid' | 'list' | 'waterfall'>('grid')
const isSelectionMode = ref(false)
const selectedImages = ref<PictureItem[]>([])
const showDownloadProgress = ref(false)
const downloadTasks = ref<DownloadTask[]>([])
const showAllDownloads = ref(false)
const downloadList = ref<DownloadTask[]>([])

// AI扩图相关
const aiOutPaintingLoading = ref(false)

// 实时搜索逻辑
let searchInputTimer: number | null = null
const onSearchInput = (e: Event) => {
  const value = (e.target as HTMLInputElement).value
  filterParams.searchText = value
  // 防抖，避免频繁请求
  if (searchInputTimer) clearTimeout(searchInputTimer)
  searchInputTimer = window.setTimeout(async () => {
    // 只用关键词搜索，不带tags/category等，调用新接口
    if (value.trim()) {
      loading.value = true
      try {
        const res = await searchPictureByKeywordUsingGet({
          searchText: value,
          page: 1,
          pageSize: 35,
          type: 'all',
        })
        if (res.data.code === 200 && res.data.data) {
          dataList.value = (res.data.data.records || []) as PictureItem[]
          total.value = Number(res.data.data.total) || 0
          // 新增：获取所有图片id，批量查询点赞/收藏状态
            const picIds = dataList.value.map(item => item.id).join(',')
          if (picIds) {
            try {
              const statusRes = await getBatchLikeFavoriteStatusUsingGet({ picIds })
              if (statusRes.data?.code === 200 && Array.isArray(statusRes.data.data)) {
                const statusMap = new Map<string, { picId: string; isLiked: boolean; isFavorited: boolean }>()
                  statusRes.data.data.forEach((item: { picId: string; isLiked: boolean; isFavorited: boolean }) => {
                  statusMap.set(String(item.picId), item)
                })
                  dataList.value.forEach(img => {
                  const status = statusMap.get(String(img.id))
                  if (status) {
                    img.liked = !!status.isLiked
                    img.favorited = !!status.isFavorited
                  }
                })
              }
            } catch {
              // 状态接口失败不影响主流程
            }
          }
        } else {
          dataList.value = []
          total.value = 0
        }
      } catch {
        dataList.value = []
        total.value = 0
      } finally {
        loading.value = false
      }
    } else {
      // 输入为空时恢复原始数据
      fetchData()
    }
  }, 300)
}

const fetchData = async () => {
  loading.value = true
  try {
    const params: API.getPictureListUsingGET2Params = {
      page: getPictureListParams.value.page,
      pageSize: viewMode.value === 'waterfall' ? 50 : 35,
      tags: filterParams.tags.join(','),
      type: 'all',
      category: filterParams.category || undefined,
      // 使用新添加的pageType字段来区分页面类型
      pageType: pageType.value,
      // 恢复searchText为undefined，不用于传递页面类型
      searchText: undefined,
    }

    // 修复：正确调用API并处理响应
    const response = await getPictureListUsingGet1(params)

    // 检查响应结构
    if (response && response.data) {
      const res = response.data

      if (res.code === 200 && res.data) {
        dataList.value = (res.data.records || []) as PictureItem[]
        total.value = Number(res.data.total) || 0
        // 新增：获取所有图片id，批量查询点赞/收藏状态
          const picIds = dataList.value.map(item => item.id).join(',')
        if (picIds) {
          try {
            const statusRes = await getBatchLikeFavoriteStatusUsingGet({ picIds })
            if (statusRes.data?.code === 200 && Array.isArray(statusRes.data.data)) {
              const statusMap = new Map<string, { picId: string; isLiked: boolean; isFavorited: boolean }>()
              statusRes.data.data.forEach((item: { picId: string; isLiked: boolean; isFavorited: boolean }) => {
                statusMap.set(String(item.picId), item)
              })
                dataList.value.forEach(img => {
                const status = statusMap.get(String(img.id))
                if (status) {
                  img.liked = !!status.isLiked
                  img.favorited = !!status.isFavorited
                }
              })
            }
          } catch {
            // 状态接口失败不影响主流程
            console.warn('获取点赞收藏状态失败')
          }
        }
      } else {
        console.error('API返回错误:', res.message)
        message.error('获取数据失败，' + (res.message || '未知错误'))
      }
    } else {
      console.error('响应结构异常:', response)
      message.error('获取数据失败：响应结构异常')
    }
  } catch (error: unknown) {
    console.error('获取数据失败:', error)
    message.error('获取数据失败：' + (error instanceof Error ? error.message : '网络错误'))
  } finally {
    loading.value = false
  }
}

// 页面类型切换处理
  const handlePageTypeChange = (e: Event | string) => {
  console.log('🚀 handlePageTypeChange 被调用了！')
    console.log('传入的完整参数:', e)

  // 从事件对象中提取实际的值
    const actualValue = typeof e === 'object' && e?.target ? (e.target as HTMLInputElement)?.value : e
  console.log('实际使用的值:', actualValue)
    console.log('页面类型切换:', actualValue)

    // 确保值是有效的
    if (actualValue && ['basic', 'featured', 'ranking'].includes(actualValue as string)) {
  pageType.value = actualValue as 'basic' | 'featured' | 'ranking'
  loading.value = true

  // 添加切换动画效果 - 增强的视觉特效
  const contentSection = document.querySelector('.content-section') as HTMLElement
  if (contentSection) {
    // 增强的淡出效果
    contentSection.style.transition = 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)'
    contentSection.style.opacity = '0.4' // 适度的透明度
    contentSection.style.transform = 'scale(0.96) rotateX(2deg)' // 添加轻微的3D旋转效果
    contentSection.style.filter = 'blur(1px) brightness(0.9)' // 适度模糊 + 亮度调整
    contentSection.style.perspective = '1000px' // 3D透视效果

    // 添加动态阴影效果
    contentSection.style.boxShadow = '0 20px 40px rgba(0, 0, 0, 0.15)'

    // 确保loading元素不受父元素动画影响
    const loadingElements = contentSection.querySelectorAll(
        '.ant-spin, .ant-spin-dot, .ant-spin-text'
    )
    loadingElements.forEach((element: Element) => {
      const el = element as HTMLElement
      el.style.zIndex = '9999'
      el.style.position = 'relative'
      el.style.filter = 'none'
      el.style.backdropFilter = 'none'
      el.style.transform = 'none'
    })
  }

  // 重置分页到第一页
  getPictureListParams.value.page = 1
  console.log('分页已重置到第1页')

  // 根据页面类型切换数据源
  switch (actualValue) {
    case 'basic':
      // 基础页面：显示普通图片列表，携带基础标识
      console.log('🔥 进入 basic case 分支')
      console.log('切换到基础页面') // 添加调试日志
      console.log('准备调用 fetchDataWithPageType("basic")')
      fetchDataWithPageType('basic')
      console.log('🔥 fetchDataWithPageType("basic") 调用完成')
      break
    case 'featured':
      // 精选推荐：显示热门推荐数据，携带精选标识
      console.log('🔥 进入 featured case 分支')
      console.log('切换到精选推荐') // 添加调试日志
      console.log('准备调用 fetchDataWithPageType("featured")')
      fetchDataWithPageType('featured')
      console.log('🔥 fetchDataWithPageType("featured") 调用完成')
      break
    case 'ranking':
      // 热度排行：获取热度排行数据，携带热度标识
      console.log('🔥 进入 ranking case 分支')
      console.log('切换到热度排行') // 添加调试日志
      console.log('准备调用 fetchDataWithPageType("ranking")')
      fetchDataWithPageType('ranking')
      console.log('🔥 fetchDataWithPageType("ranking") 调用完成')
      break
    default:
      console.error('未知的页面类型:', actualValue)
      break
  }

  console.log('=== 页面类型切换处理完成 ===')
    } else {
      console.error('无效的页面类型:', actualValue)
    }
  }

  // 视图模式切换处理
  const handleViewModeChange = (newViewMode: 'grid' | 'list' | 'waterfall') => {
    console.log('🔄 视图模式切换:', viewMode.value, '->', newViewMode)

    // 如果视图模式没有变化，不需要重新请求
    if (viewMode.value === newViewMode) {
      return
    }

    // 更新视图模式
    viewMode.value = newViewMode

    // 重置分页到第一页
    getPictureListParams.value.page = 1

    // 根据当前页面类型重新获取数据
    fetchDataWithPageType(pageType.value)
}

// 根据页面类型获取数据，携带对应的标识参数
const fetchDataWithPageType = async (pageTypeValue: 'basic' | 'featured' | 'ranking') => {
  console.log('🔥 fetchDataWithPageType 被调用了！')
  console.log('传入的页面类型:', pageTypeValue)
  console.log('开始获取数据，页面类型:', pageTypeValue) // 添加调试日志
  loading.value = true
  try {
    const params: API.getPictureListUsingGET2Params = {
      page: getPictureListParams.value.page,
        pageSize: viewMode.value === 'waterfall' ? 100 : 35, // 瀑布流显示100张
      tags: filterParams.tags.join(','),
      // 恢复原有的type参数
      type: 'all',
      category: filterParams.category || undefined,
      // 使用新添加的pageType字段来区分页面类型
      pageType: pageTypeValue,
        // 如果是热度排行页面，携带热度筛选参数
        popularityType: pageTypeValue === 'ranking' ? popularityFilter.value : undefined,
      searchText: undefined,
    }

    console.log('请求参数:', params) // 添加调试日志

    // 修复：正确调用API并处理响应
    const response = await getPictureListUsingGet1(params)
    console.log('完整响应:', response) // 添加调试日志

    // 检查响应结构
    if (response && response.data) {
      const res = response.data
      console.log('请求响应:', res) // 添加调试日志

      if (res.code === 200 && res.data) {
        dataList.value = (res.data.records || []) as PictureItem[]
        total.value = Number(res.data.total) || 0

        // 获取所有图片id，批量查询点赞/收藏状态
          const picIds = dataList.value.map(item => item.id).join(',')
        if (picIds) {
          try {
            const statusRes = await getBatchLikeFavoriteStatusUsingGet({ picIds })
            if (statusRes.data?.code === 200 && Array.isArray(statusRes.data.data)) {
              const statusMap = new Map<string, { picId: string; isLiked: boolean; isFavorited: boolean }>()
              statusRes.data.data.forEach((item: { picId: string; isLiked: boolean; isFavorited: boolean }) => {
                statusMap.set(String(item.picId), item)
              })
                dataList.value.forEach(img => {
                const status = statusMap.get(String(img.id))
                if (status) {
                  img.liked = !!status.isLiked
                  img.favorited = !!status.isFavorited
                }
              })
            }
          } catch (e) {
            // 状态接口失败不影响主流程
            console.warn('获取点赞收藏状态失败:', e)
          }
        }

        console.log('数据获取成功，共', dataList.value.length, '条记录')
      } else {
        console.error('API返回错误:', res.message)
        message.error('获取数据失败，' + (res.message || '未知错误'))
      }
    } else {
      console.error('响应结构异常:', response) // 添加调试日志
      message.error('获取数据失败：响应结构异常')
    }
  } catch (error: Error | unknown) {
    console.error('请求失败:', error) // 添加调试日志
    const errorMessage = error instanceof Error ? error.message : '网络错误'
    message.error('获取数据失败：' + errorMessage)
  } finally {
    loading.value = false
    restoreContentAnimation()
  }
}

// 恢复内容区域的动画效果
const restoreContentAnimation = () => {
  setTimeout(() => {
    const contentSection = document.querySelector('.content-section') as HTMLElement
    if (contentSection) {
      // 增强的淡入效果 - 减少抖动，更加平滑
      contentSection.style.transition = 'all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)'
      contentSection.style.opacity = '1'
      contentSection.style.transform = 'scale(1.03) rotateX(0deg)' // 减少放大幅度
      contentSection.style.filter = 'blur(0px) brightness(1)' // 恢复清晰度和亮度
      contentSection.style.boxShadow = '0 8px 25px rgba(0, 0, 0, 0.1)' // 恢复正常阴影

      // 确保loading元素在恢复过程中保持独立
      const loadingElements = contentSection.querySelectorAll(
          '.ant-spin, .ant-spin-dot, .ant-spin-text'
      )
      loadingElements.forEach((element: Element) => {
        const el = element as HTMLElement
        el.style.zIndex = '9999'
        el.style.position = 'relative'
        el.style.filter = 'none'
        el.style.backdropFilter = 'none'
        el.style.transform = 'none'
      })

      // 减少抖动的多阶段效果
      setTimeout(() => {
        contentSection.style.transition = 'all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)'
        contentSection.style.transform = 'scale(0.99) rotateX(-0.5deg)' // 减少缩小幅度和3D角度
      }, 200)

      setTimeout(() => {
        contentSection.style.transition = 'all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)'
        contentSection.style.transform = 'scale(1.01) rotateX(0.2deg)' // 减少放大幅度和3D角度
      }, 500)

      setTimeout(() => {
        contentSection.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)'
        contentSection.style.transform = 'scale(1) rotateX(0deg)' // 最终恢复
        contentSection.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.08)' // 最终阴影
      }, 800)
    }
    loading.value = false
  }, 300) // 延长一点时间，让特效更明显
}

// 切换到热度排行
const switchToRanking = () => {
  pageType.value = 'ranking'
  handlePageTypeChange('ranking')
}

  // 热度筛选处理
  const handlePopularityFilterChange = (e: Event | string) => {
    // 从事件对象中正确提取值
    const value = e && typeof e === 'object' && 'target' in e ? (e.target as HTMLInputElement)?.value : e
    console.log('🔥 热度筛选切换:', value)
    console.log('🔥 事件对象:', e)
    
    // 确保值是有效的
    if (value && ['yesterday', 'lastWeek', 'lastMonth'].includes(value as 'yesterday' | 'lastWeek' | 'lastMonth')) {
      popularityFilter.value = value as 'yesterday' | 'lastWeek' | 'lastMonth'
      
      // 重置分页到第一页
      getPictureListParams.value.page = 1
      
      // 重新获取数据，携带热度筛选参数
      fetchDataWithPopularityFilter()
    } else {
      console.error('🔥 无效的热度筛选值:', value)
    }
  }

  // 根据热度筛选获取数据
  const fetchDataWithPopularityFilter = async () => {
    console.log('🔥 fetchDataWithPopularityFilter 被调用了！')
    console.log('热度筛选类型:', popularityFilter.value)
    
    loading.value = true
    try {
      // 使用现有的API参数结构，通过searchText传递热度筛选信息
      const params: API.getPictureListUsingGET2Params = {
        page: getPictureListParams.value.page,
        pageSize: viewMode.value === 'waterfall' ? 100 : 35, // 瀑布流显示100张
        tags: filterParams.tags.join(','),
        type: 'all',
        category: filterParams.category || undefined,
        pageType: 'ranking',
        // 使用新的popularityType字段传递热度筛选参数
        popularityType: popularityFilter.value,
        searchText: undefined,
      }

      console.log('请求参数:', params)

      const response = await getPictureListUsingGet1(params)
      console.log('完整响应:', response)

      if (response && response.data) {
        const res = response.data
        console.log('请求响应:', res)

        if (res.code === 200 && res.data) {
          dataList.value = (res.data.records || []) as PictureItem[]
          total.value = Number(res.data.total) || 0

          // 获取所有图片id，批量查询点赞/收藏状态
          const picIds = dataList.value.map(item => item.id).join(',')
          if (picIds) {
            try {
              const statusRes = await getBatchLikeFavoriteStatusUsingGet({ picIds })
              if (statusRes.data?.code === 200 && Array.isArray(statusRes.data.data)) {
                const statusMap = new Map<string, { picId: string; isLiked: boolean; isFavorited: boolean }>()
                statusRes.data.data.forEach((item: { picId: string; isLiked: boolean; isFavorited: boolean }) => {
                  statusMap.set(String(item.picId), item)
                })
                dataList.value.forEach(img => {
                  const status = statusMap.get(String(img.id))
                  if (status) {
                    img.liked = !!status.isLiked
                    img.favorited = !!status.isFavorited
                  }
                })
              }
            } catch (e) {
              console.warn('获取点赞收藏状态失败:', e)
            }
          }

          console.log('数据获取成功，共', dataList.value.length, '条记录')
        } else {
          console.error('API返回错误:', res.message)
          message.error('获取数据失败，' + (res.message || '未知错误'))
        }
      } else {
        console.error('响应结构异常:', response)
        message.error('获取数据失败：响应结构异常')
      }
    } catch (error: Error | unknown) {
      console.error('请求失败:', error) // 添加调试日志
      const errorMessage = error instanceof Error ? error.message : '网络错误'
      message.error('获取数据失败：' + errorMessage)
    } finally {
      loading.value = false
      restoreContentAnimation()
    }
  }

// 颜色搜索
const searchByColor = async () => {
  if (!filterParams.color) {
    message.warning('请选择颜色')
    return
  }

  loading.value = true
  try {
    const colorCode = filterParams.color.replace('#', '')
    const res = await searchByColorUsingGet1({
      color: colorCode,
    })

    if (res.data.code === 200) {
      dataList.value = (Array.isArray(res.data.data) ? res.data.data : []) as PictureItem[]
      total.value = dataList.value.length
    } else {
      message.warn(res.data.message || '搜索失败')
    }
  } catch {
    console.error('颜色搜索错误：')
    message.error('搜索失败，未知错误')
  } finally {
    loading.value = false
  }
}

// 切换分类
const toggleCategory = (category: string) => {
  filterParams.category = filterParams.category === category ? '' : category
}

// 切换标签
const toggleTag = (tag: string) => {
  const index = filterParams.tags.indexOf(tag)
  if (index > -1) {
    filterParams.tags.splice(index, 1)
  } else {
    filterParams.tags.push(tag)
  }
}

// 切换选择模式
const toggleSelectionMode = () => {
  isSelectionMode.value = !isSelectionMode.value
  if (!isSelectionMode.value) {
    selectedImages.value = []
  }
}

// 处理图片点击
const handleImageClick = (image: PictureItem) => {
  if (isSelectionMode.value) {
      const index = selectedImages.value.findIndex(img => img.url === image.url)
    if (index > -1) {
      selectedImages.value.splice(index, 1)
    } else {
      selectedImages.value.push(image)
    }
  } else {
    showImageDetails(image)
  }
}

// 处理表格选择
const handleTableSelection = (selectedRowKeys: string[], selectedRows: PictureItem[]) => {
  selectedImages.value = selectedRows
}

// 单个图片下载
const downloadImage = async (image: PictureItem) => {
  const taskId = Date.now().toString()
  downloadTasks.value.push({
    id: taskId,
    filename: image.name || '未命名图片',
    status: '下载中',
    progress: 0,
  })

  try {
    const link = document.createElement('a')
    link.href = `${IMAGE_PREFIX}${image.url}`
    link.download = image.name || '未命名图片'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)

    // 更新下载状态
      const task = downloadTasks.value.find(t => t.id === taskId)
    if (task) {
      task.status = '已完成'
      task.progress = 100
    }
  } catch {
    const task = downloadTasks.value.find(t => t.id === taskId)
    if (task) {
      task.status = '已失败'
    }
    message.error('下载失败')
  }
}

// 批量下载
const batchDownload = () => {
    selectedImages.value.forEach(image => {
    downloadImage(image)
  })
}

// 下载全部图片
const downloadAllImages = () => {
    dataList.value.forEach(image => {
    downloadImage(image)
  })
}

// 应用筛选条件
const applyFilters = () => {
  getPictureListParams.value.page = 1
  // 根据当前页面类型获取数据
  fetchDataWithPageType(pageType.value)
}

// 重置筛选条件
const resetFilters = () => {
  filterParams.category = ''
  filterParams.tags = []
  filterParams.searchText = ''
  filterParams.color = '#ffffff'
  getPictureListParams.value.page = 1
  // 根据当前页面类型获取数据
  fetchDataWithPageType(pageType.value)
}

// 获取分类和标签
const fetchMetadata = async () => {
  try {
    const [categoriesRes, tagsRes] = await Promise.all([
      getCategoriesUsingGet1(),
      getTagsUsingGet1(),
    ])

    console.log(categoriesRes, tagsRes)

    if (categoriesRes.data.code === 200) {
      categories.value = categoriesRes.data.data as string[]
    }
    if (tagsRes.data.code === 200) {
      tags.value = tagsRes.data.data as string[]
    }
  } catch {
    message.error('获取分类和标签失败')
  }
}

// 刷新当前页
const refreshCurrentPage = () => {
  // 根据当前页面类型获取数据
  fetchDataWithPageType(pageType.value)
}

// 处理分页变化
const handlePageChange = (page: number) => {
  getPictureListParams.value.page = page
  // 根据当前页面类型获取数据
  fetchDataWithPageType(pageType.value)
}

// 处理每页条数变化
const handleSizeChange = (current: number, size: number) => {
  getPictureListParams.value.page = 1
  getPictureListParams.value.pageSize = size
  fetchData()
}

// 显示图片详情
const showImageDetails = (image: PictureItem) => {
  if (!image) return
  selectedImage.value = { ...image }
  detailVisible.value = true
}

// 关闭图片详情
const closeImageDetails = () => {
  detailVisible.value = false
  selectedImage.value = null
}

// 处理图片加载错误
const handleImageError = (e: Event) => {
  const img = e.target as HTMLImageElement
  img.src = '/src/assets/default_avatar.png'
}

// 解析标签
const parseTags = (tags: string | string[]) => {
  if (!tags) return []
  if (Array.isArray(tags)) return tags
  try {
    return typeof tags === 'string' ? JSON.parse(tags) : []
  } catch {
    return []
  }
}

const clearCompletedTasks = () => {
    downloadTasks.value = downloadTasks.value.filter(task => task.status === '下载中')
}

// 计算显示的下载列表
const displayDownloads = computed(() => {
  if (showAllDownloads.value) {
    return downloadList.value.slice(0, 10) // 限制最多显示10个任务
  }
  return downloadList.value.slice(0, 5)
})

// 计算剩余任务数
const remainingDownloads = computed(() => {
  const displayCount = showAllDownloads.value ? 10 : 5
  return Math.max(0, downloadList.value.length - displayCount)
})

// 获取表格列定义
const getColumns = () => {
  return [
    {
      title: '预览',
      dataIndex: 'thumbnailUrl',
      width: 100,
    },
    {
      title: '名称',
      dataIndex: 'name',
      customRender: ({ record }: { record: PictureItem }) => highlightKeyword(record.name).html,
    },
    {
      title: '分类',
      dataIndex: 'category',
    },
    {
      title: '标签',
      dataIndex: 'tags',
    },
    {
      title: '尺寸',
      dataIndex: 'dimensions',
      customRender: ({ record }: { record: PictureItem }) => `${record.picWidth} x ${record.picHeight}`,
    },
    {
      title: '大小',
      dataIndex: 'picSize',
      customRender: ({ record }: { record: PictureItem }) => `${(Number(record.picSize) / 1024).toFixed(2)} KB`,
    },
    {
      title: '点赞数',
      dataIndex: 'likeCount',
      customRender: ({ record }: { record: PictureItem }) => formatCount(record.likeCount),
    },
    {
      title: '收藏数',
      dataIndex: 'favoriteCount',
      customRender: ({ record }: { record: PictureItem }) => formatCount(record.favoriteCount),
    },
    {
      title: '更新时间',
      dataIndex: 'updateTime',
      customRender: ({ record }: { record: PictureItem }) =>
        record.updateTime ? formatDate(Number(record.updateTime)) : '-',
    },
      {
        title: '操作',
        dataIndex: 'operation',
        width: 80,
        fixed: 'right',
      },
  ]
}

// 处理AI扩图请求
const handleAIOutPainting = async () => {
  if (!selectedImage.value) return

  aiOutPaintingLoading.value = true
  try {
    const params = {
      pictureId: selectedImage.value.id,
    }

    const res = await createPictureOutPaintingTaskUsingPost(params)
    if (res.data.code === 200) {
      message.success('任务创建成功')
    } else {
      message.error(res.data.message || '创建任务失败')
    }
  } catch {
    message.error('创建任务失败')
  } finally {
    aiOutPaintingLoading.value = false
  }
}

// 单张点赞方法
const handleLike = async (image: PictureItem) => {
  try {
    if (image.liked) {
      // 已点赞，发起取消点赞
      const res = await cancelLikePictureUsingPost1(String(image.id))
      if (res.data?.code === 200) {
        message.success('取消点赞成功')
        image.likeCount = Math.max(0, (image.likeCount || 1) - 1)
        image.liked = false
      } else {
        message.error(res.data?.message || '取消点赞失败')
      }
    } else {
      // 未点赞，发起点赞
      const res = await likePictureUsingPost1(String(image.id))
      if (res.data?.code === 200) {
        message.success('点赞成功')
        image.likeCount = (image.likeCount || 0) + 1
        image.liked = true
      } else {
        message.error(res.data?.message || '点赞失败')
      }
    }
  } catch {
    message.error('操作失败')
  }
}

// 单张收藏方法
const handleFavorite = async (image: PictureItem) => {
  try {
    if (image.favorited) {
      // 已收藏，发起取消收藏
      const res = await batchCancelFavoriteUsingPost1(String(image.id))
      if (res.data?.code === 200) {
        message.success('取消收藏成功')
        image.favoriteCount = Math.max(0, (image.favoriteCount || 1) - 1)
        image.favorited = false
      } else {
        message.error(res.data?.message || '取消收藏失败')
      }
    } else {
      // 未收藏，发起收藏
      const res = await batchAddFavoriteUsingPost1(String(image.id))
      if (res.data?.code === 200) {
        message.success('收藏成功')
        image.favoriteCount = (image.favoriteCount || 0) + 1
        image.favorited = true
      } else {
        message.error(res.data?.message || '收藏失败')
      }
    }
  } catch {
    message.error('操作失败')
  }
}

// 批量收藏方法（只处理未收藏的图片）
const handleBatchFavorite = async () => {
  if (!selectedImages.value.length) {
    message.warning('请选择要收藏的图片')
    return
  }
    const toAdd = selectedImages.value.filter(img => !img.favorited)
  if (!toAdd.length) {
    message.info('所选图片均已收藏')
    return
  }
  try {
      const picIds = toAdd.map(img => img.id).join(',')
    const res = await batchAddFavoriteUsingPost1(picIds)
    if (res.data?.code === 200) {
      message.success('批量收藏成功')
        toAdd.forEach(img => {
        img.favorited = true
        img.favoriteCount = (img.favoriteCount || 0) + 1
      })
    } else {
      message.error(res.data?.message || '批量收藏失败')
    }
  } catch {
    message.error('批量操作失败')
  }
}

// 批量点赞方法（只处理未点赞的图片）
const handleBatchLike = async () => {
  if (!selectedImages.value.length) {
    message.warning('请选择要点赞的图片')
      
    return
  }
    const toAdd = selectedImages.value.filter(img => !img.liked)
  if (!toAdd.length) {
    message.info('所选图片均已点赞')
    return
  }
  try {
      const picIds = toAdd.map(img => img.id).join(',')
    const res = await likePictureUsingPost1(picIds)
    if (res.data?.code === 200) {
      message.success('批量点赞成功')
        toAdd.forEach(img => {
        img.liked = true
        img.likeCount = (img.likeCount || 0) + 1
      })
    } else {
      message.error(res.data?.message || '批量点赞失败')
    }
  } catch {
    message.error('批量操作失败')
  }
}

// 批量取消收藏方法
const handleBatchCancelFavorite = async () => {
  if (!selectedImages.value.length) {
    message.warning('请选择要取消收藏的图片')
    return
  }
    const toCancel = selectedImages.value.filter(img => img.favorited)
  if (!toCancel.length) {
    message.info('所选图片均未收藏')
    return
  }
  try {
      const picIds = toCancel.map(img => img.id).join(',')
    const res = await batchCancelFavoriteUsingPost1(picIds)
    if (res.data?.code === 200) {
      message.success('批量取消收藏成功')
        toCancel.forEach(img => {
        img.favorited = false
        img.favoriteCount = Math.max(0, (img.favoriteCount || 1) - 1)
      })
    } else {
      message.error(res.data?.message || '批量取消收藏失败')
    }
  } catch {
    message.error('批量操作失败')
  }
}

// 批量取消点赞方法
const handleBatchCancelLike = async () => {
  if (!selectedImages.value.length) {
    message.warning('请选择要取消点赞的图片')
    return
  }
    const toCancel = selectedImages.value.filter(img => img.liked)
  if (!toCancel.length) {
    message.info('所选图片均未点赞')
    return
  }
  try {
      const picIds = toCancel.map(img => img.id).join(',')
    const res = await cancelLikePictureUsingPost1(picIds)
    if (res.data?.code === 200) {
      message.success('批量取消点赞成功')
        toCancel.forEach(img => {
        img.liked = false
        img.likeCount = Math.max(0, (img.likeCount || 1) - 1)
      })
    } else {
      message.error(res.data?.message || '批量取消点赞失败')
    }
  } catch {
    message.error('批量操作失败')
  }
}

const toggleSelectAllOnPage = () => {
  if (selectedImages.value.length === dataList.value.length && dataList.value.length > 0) {
    selectedImages.value = []
  } else {
    selectedImages.value = [...dataList.value]
  }
}



// 图片加载完成处理
const handleImageLoad = (event: Event) => {
  const img = event.target as HTMLImageElement
  const container = img.closest('.waterfall-item')
  if (container) {
    // 设置图片容器高度为图片的实际高度，保持宽高比
    const width = container.clientWidth
    const height = (img.naturalHeight / img.naturalWidth) * width
    ;(container as HTMLElement).style.height = `${height}px`

    // 添加可见类以触发动画
    setTimeout(() => {
      container.classList.add('visible')
    }, 50)
  }
}

// 添加滚动事件监听器
const setupScrollAnimation = () => {
  const observer = new IntersectionObserver(
      entries => {
        entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add('visible')
        }
      })
    },
    {
      threshold: 0.1,
      }
  )

  // 观察所有瀑布流项目
  document.querySelectorAll('.waterfall-item').forEach((item: Element) => {
    observer.observe(item)
  })

  // 组件卸载时断开观察
  onUnmounted(() => {
    observer.disconnect()
  })
}

// 监听数据变化以设置滚动动画
watch(
  () => dataList,
  () => {
    nextTick(() => {
      if (viewMode.value === 'waterfall') {
        setupScrollAnimation()
      }
    })
  },
    { deep: true }
)

// 监听视图模式变化
watch(
  () => viewMode.value,
    newVal => {
    if (newVal === 'waterfall') {
      nextTick(() => {
        setupScrollAnimation()
      })
    }
    }
)

// 页面加载时获取数据
onMounted(() => {
  fetchMetadata()
  // 根据默认页面类型获取数据，携带对应的标识参数
  fetchDataWithPageType(pageType.value)
})

// 暴露给模板使用的变量和方法
defineExpose({
  filterParams,
  getPictureListParams,
  dataList,
  total,
  loading,
  categories,
  tags,
  detailVisible,
  selectedImage,
  viewMode,
  isSelectionMode,
  selectedImages,
  showDownloadProgress,
  downloadTasks,
  showAllDownloads,
  downloadList,
  aiOutPaintingLoading,
  IMAGE_PREFIX,
  handleAIOutPainting,
  fetchData,
  searchByColor,
  toggleCategory,
  toggleTag,
  toggleSelectionMode,
  handleImageClick,
  handleTableSelection,
  downloadImage,
  batchDownload,
  downloadAllImages,
  applyFilters,
  resetFilters,
  refreshCurrentPage,
  handlePageChange,
  handleSizeChange,
  showImageDetails,
  closeImageDetails,
  handleImageError,
  parseTags,
  clearCompletedTasks,
  displayDownloads,
  formatDate,
  getColumns,
  handleFavorite,
  handleBatchFavorite,
  handleLike,
  handleBatchLike,
  handleBatchCancelFavorite,
  handleBatchCancelLike,
  toggleSelectAllOnPage,
  switchToRanking,
    handleViewModeChange,
})

// 在<script setup>顶部添加格式化方法
const formatCount = (num: number | undefined) => {
  if (!num) return 0
  if (num < 10000) return num
  return (num / 10000).toFixed(1).replace(/\.0$/, '') + 'w'
}

// 在<script setup>中添加
const rowKeyFn = (record: PictureItem) => record.url
const showTotal = () => `列表目录`

// 图片名称/描述高亮关键词，返回高亮内容和是否有命中
const highlightKeyword = (text: string) => {
  const keyword = filterParams.searchText.trim()
  if (!keyword) return { html: text, matched: false }
  // 全局不区分大小写高亮
  const reg = new RegExp(keyword.replace(/[.*+?^${}()|[\\]\\]/g, '\\$&'), 'gi')
  let matched = false
    const html = text.replace(reg, match => {
    matched = true
    return `${match}`
  })
  return { html, matched }
}


</script>

<style scoped>
/* 瀑布流视图样式 */
.waterfall-view {
  column-count: 4;
  column-gap: 16px;
  padding: 16px 0;
  width: 100%;
  animation: fadeIn 0.5s ease-in-out;
}

  .waterfall-item {
    break-inside: avoid;
    margin-bottom: 16px;
    transition:
      transform 0.3s ease,
      box-shadow 0.3s ease;
    border-radius: 8px;
    overflow: hidden;
    background: var(--theme-surface);
    box-shadow: 0 2px 8px var(--theme-shadow);
    opacity: 0;
    animation: fadeInUp 0.5s ease-out forwards;
  }

.waterfall-item.visible {
  opacity: 1;
}

  .waterfall-item:hover {
    transform: translateY(-4px);
    box-shadow: 0 6px 16px var(--theme-shadow);
  }

.waterfall-image-wrapper {
  position: relative;
  width: 100%;
  overflow: hidden;
}

.waterfall-image {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 0.3s ease;
}

.waterfall-item:hover .waterfall-image {
  transform: scale(1.03);
}

.waterfall-info {
  padding: 12px;
}

  .waterfall-name {
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--theme-text);
    transition: color 0.3s ease;
  }

  .waterfall-meta {
    display: flex;
    justify-content: space-between;
    font-size: 12px;
    color: var(--theme-textSecondary);
    transition: color 0.3s ease;
  }

  .waterfall-actions {
    display: flex;
    justify-content: space-between;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--theme-border);
    transition: border-color 0.3s ease;
  }

  .waterfall-action-btn {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: var(--theme-textSecondary);
    cursor: pointer;
    transition: color 0.3s;
  }

.waterfall-action-btn:hover {
  color: #1890ff;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 响应式调整 */
@media (min-width: 1200px) {
  .waterfall-view {
    column-count: 6;
    column-gap: 12px;
  }
  .waterfall-item {
    margin-bottom: 12px;
  }
}

@media (min-width: 992px) and (max-width: 1199px) {
  .waterfall-view {
    column-count: 5;
    column-gap: 10px;
  }
  .waterfall-item {
    margin-bottom: 10px;
  }
}

@media (min-width: 768px) and (max-width: 991px) {
  .waterfall-view {
    column-count: 4;
    column-gap: 8px;
  }
  .waterfall-item {
    margin-bottom: 8px;
  }
}

@media (max-width: 767px) {
  .waterfall-view {
    column-count: 2;
    column-gap: 6px;
  }
  .waterfall-item {
    margin-bottom: 6px;
  }
}

  .home-container {
    min-height: 100vh;
    height: 100vh;
    background: var(--theme-background);
    padding: 24px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transition: all 0.3s ease;
  }

  /* 热门推荐区域样式 */
  .hot-recommend-section {
    margin-bottom: 24px;
    background: linear-gradient(135deg, var(--theme-primary) 0%, var(--theme-secondary) 100%);
    border-radius: 12px;
    padding: 24px;
    color: var(--theme-surface);
    transition: all 0.3s ease;
  }

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.section-icon {
  font-size: 24px;
  color: #ffd700;
}

  .section-title {
    font-size: 24px;
    font-weight: bold;
    margin: 0;
    color: var(--theme-surface);
    transition: color 0.3s ease;
  }

.section-subtitle {
  font-size: 14px;
  opacity: 0.8;
  margin-left: 8px;
}

  .header-right .ant-btn {
    color: var(--theme-surface);
    border-color: rgba(255, 255, 255, 0.3);
    transition: all 0.3s ease;
  }

  .header-right .ant-btn:hover {
    color: #ffd700;
    border-color: #ffd700;
  }

.hot-recommend-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

  .hot-recommend-item {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    transition: all 0.3s ease;
    backdrop-filter: blur(10px);
  }

.hot-recommend-item:hover {
  transform: translateY(-4px);
  background: rgba(255, 255, 255, 0.2);
}

.item-image {
  position: relative;
  width: 100%;
  height: 120px;
  overflow: hidden;
}

.item-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s;
}

.hot-recommend-item:hover .item-image img {
  transform: scale(1.1);
}

.item-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s;
}

.hot-recommend-item:hover .item-overlay {
  opacity: 1;
}

.overlay-content {
  color: white;
  font-size: 20px;
}

.hot-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  background: rgba(255, 215, 0, 0.9);
  color: #8b6914;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.item-info {
  padding: 12px;
}

.item-name {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-stats {
  display: flex;
  gap: 12px;
  font-size: 12px;
  opacity: 0.8;
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.page-header {
  text-align: center;
  margin-bottom: 24px;
  padding-bottom: 24px;
  border-bottom: 1px solid #f0f0f0;
  flex-shrink: 0;
}

.page-header h1 {
  font-size: 32px;
  color: #1a1a1a;
  margin-bottom: 12px;
  font-weight: 600;
}

.page-header p {
  color: #666;
  font-size: 16px;
}

  .filter-section {
    background: var(--theme-surface);
    padding: 20px;
    border-bottom: 1px solid var(--theme-border);
    flex-shrink: 0;
    transition: all 0.3s ease;
  }

.filter-row {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}

.filter-row:last-child {
  margin-bottom: 0;
}

  .filter-label {
    font-size: 15px;
    font-weight: 500;
    color: var(--theme-text);
    white-space: nowrap;
    padding-right: 16px;
    min-width: 60px;
    transition: color 0.3s ease;
  }

.filter-content {
  flex: 1;
  display: flex;
  gap: 8px;
  align-items: center;
  overflow-x: auto;
  padding-bottom: 4px;
}

.filter-content::-webkit-scrollbar {
  height: 6px;
}

.filter-content::-webkit-scrollbar-thumb {
  background: #d9d9d9;
  border-radius: 3px;
}

.filter-content::-webkit-scrollbar-track {
  background: #f0f0f0;
  border-radius: 3px;
}

.filter-button {
  height: 32px;
  padding: 0 16px;
  flex-shrink: 0;
}

/* 页面类型选择器样式 */
  .page-type-row {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--theme-border);
    transition: border-color 0.3s ease;
  }

  /* 热度筛选区域样式 */
  .popularity-filter-row {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--theme-border);
    transition: border-color 0.3s ease;
  }

  .popularity-filter-content {
    justify-content: flex-end;
    width: auto;
  }

  .popularity-filter-selector {
    display: flex;
    gap: 0;
    width: auto;
    justify-content: flex-end;
    background: var(--theme-background);
    border-radius: 8px;
    padding: 4px;
    box-shadow: 0 2px 8px var(--theme-shadow);
    transition: all 0.3s ease;
  }

  /* 深色主题下的热度筛选器优化 */
  [data-theme="dark"] .popularity-filter-selector {
    background: #333333 !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6) !important;
  }

  /* 深色主题下的热度筛选按钮优化 */
  [data-theme="dark"] .popularity-filter-selector :deep(.ant-radio-button-wrapper) {
    background-color: #333333 !important;
    border-color: #555555 !important;
    color: #ffffff !important;
  }

  [data-theme="dark"] .popularity-filter-selector :deep(.ant-radio-button-wrapper:hover) {
    background-color: #444444 !important;
    border-color: #777777 !important;
    color: #ffffff !important;
  }

  [data-theme="dark"] .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked) {
    background-color: #555555 !important;
    border-color: #777777 !important;
    color: #ffffff !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
  }

  [data-theme="dark"] .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked:hover) {
    background-color: #666666 !important;
    border-color: #888888 !important;
    color: #ffffff !important;
  }

  .popularity-filter-selector :deep(.ant-radio-button-wrapper) {
    height: 36px;
    padding: 0 20px;
    border-radius: 0;
    border: none;
    background: transparent;
    color: #666;
    font-weight: 600;
    font-size: 14px;
    font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    position: relative;
    overflow: hidden;
    flex: 1;
    min-width: 80px;
    max-width: none;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    white-space: nowrap;
  }

  .popularity-filter-selector :deep(.ant-radio-button-wrapper::before) {
    display: none;
  }

  .popularity-filter-selector :deep(.ant-radio-button-wrapper:hover) {
    background: rgba(255, 77, 79, 0.1);
    color: #ff4d4f;
    transform: translateY(-1px);
  }

  .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked) {
    background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);
    border: none;
    color: white;
    box-shadow: 0 4px 16px rgba(255, 77, 79, 0.3);
    transform: translateY(-1px);
  }

  .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked:hover) {
    background: linear-gradient(135deg, #ff7875 0%, #ffa39e 100%);
    box-shadow: 0 6px 20px rgba(255, 77, 79, 0.4);
  }

  .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked::after) {
    display: none;
  }

  .popularity-icon {
    font-size: 16px;
    display: inline-block;
    transition: transform 0.3s ease;
  }

  .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked) .popularity-icon {
    animation: popularityIconPulse 0.6s ease-out;
  }

  @keyframes popularityIconPulse {
    0% {
      transform: scale(1);
    }
    50% {
      transform: scale(1.2);
    }
    100% {
      transform: scale(1);
    }
  }

  .popularity-text {
    font-weight: 600;
    letter-spacing: 0.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

.page-type-content {
  width: 100%;
  justify-content: center;
}

.page-type-wrapper {
  width: 100%;
  max-width: none;
  margin: 0;
  text-align: center;
}

  .page-type-selector {
    display: flex;
    gap: 0;
    width: 100%;
    justify-content: center;
    background: var(--theme-background);
    border-radius: 8px;
    padding: 4px;
    box-shadow: 0 2px 8px var(--theme-shadow);
    transition: all 0.3s ease;
  }

  /* 深色主题下的页面类型选择器优化 */
  [data-theme="dark"] .page-type-selector {
    background: #333333 !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6) !important;
  }

  /* 深色主题下的页面类型按钮优化 */
  [data-theme="dark"] .page-type-selector :deep(.ant-radio-button-wrapper) {
    background-color: #333333 !important;
    border-color: #555555 !important;
    color: #ffffff !important;
  }

  [data-theme="dark"] .page-type-selector :deep(.ant-radio-button-wrapper:hover) {
    background-color: #444444 !important;
    border-color: #777777 !important;
    color: #ffffff !important;
  }

  [data-theme="dark"] .page-type-selector :deep(.ant-radio-button-wrapper-checked) {
    background-color: #555555 !important;
    border-color: #777777 !important;
    color: #ffffff !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
  }

  [data-theme="dark"] .page-type-selector :deep(.ant-radio-button-wrapper-checked:hover) {
    background-color: #666666 !important;
    border-color: #888888 !important;
    color: #ffffff !important;
  }

.page-type-selector :deep(.ant-radio-button-wrapper) {
  height: 36px;
  padding: 0 32px;
  border-radius: 0;
  border: none;
  background: transparent;
  color: #666;
  font-weight: 600;
  font-size: 15px;
  font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
  flex: 1;
  max-width: none;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.page-type-selector :deep(.ant-radio-button-wrapper::before) {
  display: none;
}

.page-type-selector :deep(.ant-radio-button-wrapper:hover) {
  background: rgba(24, 144, 255, 0.1);
  color: #1890ff;
  transform: translateY(-1px);
}

.page-type-selector :deep(.ant-radio-button-wrapper-checked) {
  background: linear-gradient(135deg, #1890ff 0%, #40a9ff 100%);
  border: none;
  color: white;
  box-shadow: 0 4px 16px rgba(24, 144, 255, 0.3);
  transform: translateY(-1px);
}

.page-type-selector :deep(.ant-radio-button-wrapper-checked:hover) {
  background: linear-gradient(135deg, #40a9ff 0%, #69c0ff 100%);
  box-shadow: 0 6px 20px rgba(24, 144, 255, 0.4);
}

.page-type-selector :deep(.ant-radio-button-wrapper-checked::after) {
  display: none;
}

.button-icon {
  font-size: 18px;
  display: inline-block;
  transition: transform 0.3s ease;
}

.page-type-selector :deep(.ant-radio-button-wrapper-checked) .button-icon {
  animation: iconPulse 0.6s ease-out;
}

@keyframes iconPulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}

.button-text {
  font-weight: 600;
  letter-spacing: 0.5px;
}

.page-type-hint {
  margin-bottom: 16px;
  padding: 12px 20px;
  background: linear-gradient(135deg, #f8f9ff 0%, #e8f4ff 100%);
  border-radius: 12px;
  border: 1px solid #e1f0ff;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif;
}

.hint-icon {
  font-size: 18px;
  animation: bounce 2s infinite;
}

.hint-text {
  font-size: 14px;
  color: #1890ff;
  font-weight: 500;
  letter-spacing: 0.5px;
}

@keyframes bounce {
  0%,
  20%,
  50%,
  80%,
  100% {
    transform: translateY(0);
  }
  40% {
    transform: translateY(-5px);
  }
  60% {
    transform: translateY(-3px);
  }
}

  .operation-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid var(--theme-border);
    transition: border-color 0.3s ease;
  }

  .toolbar-section {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px;
    background: var(--theme-surface);
    border-bottom: 1px solid var(--theme-border);
    flex-shrink: 0;
    transition: all 0.3s ease;
  }

  .selection-info {
    color: var(--theme-primary);
    font-weight: 500;
    transition: color 0.3s ease;
  }

  .content-section {
    flex: 1;
    overflow: auto;
    padding: 20px;
    display: flex;
    flex-direction: column;
    background: var(--theme-background);
    transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    will-change: opacity, transform, filter, box-shadow;
    position: relative;
    transform-style: preserve-3d; /* 保持3D变换 */
  }

/* 页面类型切换时的内容区域动画 */
.content-section.page-transitioning {
  opacity: 0.6;
  transform: scale(0.98);
}

.content-section.page-transitioning .grid-view {
  filter: blur(1px);
}

.grid-view {
  display: grid;
  grid-template-columns: repeat(7, 1fr); /* 7列 */
  grid-auto-rows: minmax(min-content, max-content);
  gap: 16px;
  padding: 16px;
  min-height: calc(100vh - 300px);
}

.grid-item {
  break-inside: avoid;
  height: 100%; /* 确保每个项目填充满格子 */
}

  .image-card {
    background: var(--theme-surface);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 2px 8px var(--theme-shadow);
    cursor: pointer;
    transition: all 0.3s ease;
    border: 2px solid transparent;
  }

.image-card.is-selected {
  border-color: #1890ff;
}

  .image-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 24px var(--theme-shadow);
  }

  .image-wrapper {
    position: relative;
    padding-top: 75%;
    overflow: hidden;
    background: var(--theme-background);
    transition: background 0.3s ease;
  }

.image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.image-card:hover .image {
  transform: scale(1.05);
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.image-card:hover .image-overlay {
  opacity: 1;
}

.overlay-content {
  color: white;
  text-align: center;
}

.overlay-content .anticon {
  font-size: 24px;
  margin-bottom: 8px;
}

.image-info {
  padding: 16px;
}

  .image-name {
    font-size: 14px;
    color: var(--theme-text);
    margin-bottom: 8px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 0.3s ease;
  }

  .image-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 12px;
    color: var(--theme-textSecondary);
    transition: color 0.3s ease;
  }

  .category {
    background: var(--theme-background);
    padding: 2px 8px;
    border-radius: 4px;
    transition: background 0.3s ease;
  }

.table-image {
  width: 80px;
  height: 60px;
  object-fit: cover;
  border-radius: 8px;
  cursor: pointer;
  transition: transform 0.3s ease;
}

.table-image:hover {
  transform: scale(1.05);
}

  .pagination-container {
    margin-top: 20px;
    padding: 20px 0;
    border-top: 1px solid var(--theme-border);
    background: var(--theme-surface);
    text-align: center;
    transition: all 0.3s ease;
  }

.image-detail {
  padding: 24px;
  box-sizing: border-box;
}

.detail-content {
  display: flex;
  gap: 24px;
  flex-wrap: wrap; /* 允许在空间不足时换行 */
}

.detail-image {
  width: 45%; /* 改为百分比宽度 */
  min-width: 300px; /* 设置最小宽度 */
  height: auto; /* 高度自适应 */
  aspect-ratio: 4/3; /* 保持固定的宽高比 */
  flex: 1; /* 允许图片区域伸缩 */
  flex-shrink: 0;
  overflow: hidden;
  border-radius: 8px;
  background-color: var(--theme-background);
  transition: all 0.3s ease;
}

.detail-info {
  flex: 1; /* 允许信息区域伸缩 */
  min-width: 300px; /* 设置最小宽度，避免内容过于压缩 */
  background: var(--theme-background);
  padding: 20px;
  border-radius: 12px;
  transition: all 0.3s ease;
}

/* 深色主题下的文字优化 */
[data-theme="dark"] .detail-info {
  background: var(--theme-surface);
}

/* 预览标题样式 */
.preview-title {
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 24px;
  color: var(--theme-text);
  transition: all 0.3s ease;
}

/* 深色主题下的标题 */
[data-theme="dark"] .preview-title {
  color: #ff00ff !important; /* 洋红色，在深色主题下醒目 */
  text-shadow: 0 1px 3px rgba(255, 0, 255, 0.5) !important;
}

/* 浅色主题下的标题 */
[data-theme="light"] .preview-title {
  color: #1890ff !important; /* 蓝色，在浅色主题下清晰 */
  text-shadow: none !important;
}

/* 信息标签样式 */
.info-label {
  width: 70px;
  flex-shrink: 0;
  font-weight: 600;
  color: var(--theme-textSecondary);
  transition: all 0.3s ease;
}

/* 深色主题下的标签 */
[data-theme="dark"] .info-label {
  color: #00ffff !important; /* 青色，在深色主题下醒目 */
  text-shadow: 0 1px 3px rgba(0, 255, 255, 0.5) !important;
}

/* 浅色主题下的标签 */
[data-theme="light"] .info-label {
  color: #666666 !important; /* 深灰色，在浅色主题下清晰 */
  text-shadow: none !important;
}

/* 信息值样式 */
.info-value {
  flex: 1;
  min-width: 0;
  font-weight: 600;
  color: var(--theme-text);
  transition: all 0.3s ease;
}

/* 深色主题下的值 */
[data-theme="dark"] .info-value {
  color: #ffff00 !important; /* 黄色，在深色主题下醒目 */
  text-shadow: 0 1px 3px rgba(255, 255, 0, 0.5) !important;
}

/* 浅色主题下的值 */
[data-theme="light"] .info-value {
  color: #333333 !important; /* 深黑色，在浅色主题下清晰 */
  text-shadow: none !important;
}

[data-theme="dark"] .empty-text {
  color: #cccccc;
}

.detail-info h3 {
  margin: 0 0 24px;
  font-size: 18px;
  font-weight: 500;
  color: var(--theme-text);
  transition: color 0.3s ease;
}

.info-item {
  display: flex;
  align-items: flex-start;
  margin-bottom: 12px;
}

.info-item .label {
  color: var(--theme-textSecondary);
  width: 70px;
  flex-shrink: 0;
  transition: color 0.3s ease;
}

.info-item .value {
  flex: 1;
  min-width: 0;
  position: relative;
  color: var(--theme-text);
  transition: color 0.3s ease;
}

.tags-list {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  overflow: hidden;
}

.info-tag {
  margin-right: 4px;
  flex-shrink: 0;
  font-size: 12px;
  line-height: 20px;
  padding: 0 8px;
  white-space: nowrap;
  background: var(--theme-primary);
  color: var(--theme-surface);
  border-color: var(--theme-primary);
  transition: all 0.3s ease;
}

/* 深色主题下的标签优化 */
[data-theme="dark"] .info-tag {
  background: #1890ff;
  border-color: #1890ff;
  color: #ffffff;
  box-shadow: 0 1px 3px rgba(24, 144, 255, 0.3);
}

[data-theme="dark"] .info-tag:hover {
  background: #40a9ff;
  border-color: #40a9ff;
  color: #ffffff;
  box-shadow: 0 2px 6px rgba(24, 144, 255, 0.4);
}

.empty-text {
  color: var(--theme-textSecondary);
  font-style: italic;
  transition: color 0.3s ease;
}

:deep(.ant-modal) {
  max-width: 95vw !important; /* 限制最大宽度为视窗的95% */
  margin: 0 auto;
}

:deep(.ant-modal-body) {
  padding: 0;
  max-height: 90vh; /* 限制最大高度为视窗的90% */
  overflow-y: auto; /* 内容过多时显示滚动条 */
}

.image-detail {
  padding: 24px;
  box-sizing: border-box;
}

.detail-image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.action-buttons {
  margin-top: 24px;
  text-align: center;
}

.action-buttons .ant-btn {
  min-width: 120px;
}

.color-selector {
  display: flex;
  align-items: center;
  gap: 8px;
}

.color-input {
  width: 44px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.color-input::-webkit-color-swatch-wrapper {
  padding: 0;
}

.color-input::-webkit-color-swatch {
  border: 1px solid #d9d9d9;
  border-radius: 4px;
}

.color-display {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 120px;
}

.color-preview {
  width: 16px;
  height: 16px;
  border-radius: 2px;
  border: 1px solid #d9d9d9;
}

.download-status {
  position: fixed;
  right: 24px;
  bottom: 24px;
  width: 320px;
  max-height: 400px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  display: flex;
  flex-direction: column;
}

.download-header {
  padding: 12px 16px;
  border-bottom: 1px solid #f0f0f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.download-list {
  padding: 8px 16px;
  overflow-y: auto;
  max-height: 300px;
  flex: 1;
}

.download-list::-webkit-scrollbar {
  width: 6px;
}

.download-list::-webkit-scrollbar-thumb {
  background: #d9d9d9;
  border-radius: 3px;
}

.download-list::-webkit-scrollbar-track {
  background: #f0f0f0;
  border-radius: 3px;
}

.download-item {
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
}

.download-item:last-child {
  border-bottom: none;
}

.download-info .filename {
  display: block;
  margin-bottom: 4px;
  font-size: 14px;
  color: rgba(0, 0, 0, 0.85);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.more-downloads {
  padding: 8px 16px;
  border-top: 1px solid #f0f0f0;
  text-align: center;
  color: rgba(0, 0, 0, 0.45);
  font-size: 14px;
}

.color-search-tip {
  font-size: 12px;
  color: #8c8c8c;
  margin-left: 8px;
}

.image-action-bar {
  display: flex;
  gap: 16px;
  margin-top: 8px;
  justify-content: flex-start;
}

  .icon-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 18px;
    color: var(--theme-textSecondary);
    cursor: pointer;
    transition: color 0.2s;
    user-select: none;
  }

.icon-btn.active {
  color: #f5222d;
}

.icon-btn:hover {
  color: #faad14;
}

  .image-desc-highlight {
    font-size: 13px;
    color: var(--theme-warning);
    margin-bottom: 4px;
    line-height: 1.4;
    transition: color 0.3s ease;
  }

  .desc-match-tip {
    color: var(--theme-warning);
    font-size: 12px;
    margin-left: 6px;
    transition: color 0.3s ease;
  }

/* 响应式设计 */
@media (max-width: 768px) {
  .home-container {
    padding: 16px;
  }

  .filter-section {
    gap: 16px;
  }

  .filter-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .filter-label {
    min-width: auto;
    padding-right: 0;
  }

  .filter-content {
    width: 100%;
    justify-content: flex-start;
  }

  /* 页面类型选择器移动端优化 */
  .page-type-row {
    margin-top: 20px;
    padding-top: 16px;
  }

    /* 热度筛选移动端优化 */
    .popularity-filter-row {
      margin-top: 12px;
      padding-top: 12px;
    }

    .popularity-filter-content {
      justify-content: flex-end;
      width: auto;
    }

    .popularity-filter-selector {
      flex-direction: row;
      gap: 0;
      width: auto;
      justify-content: flex-end;
    }

    .popularity-filter-selector :deep(.ant-radio-button-wrapper) {
      width: auto;
      height: 44px;
      justify-content: center;
      border-radius: 0;
      flex: 1;
      min-width: 70px;
      max-width: none;
      font-size: 13px;
      padding: 0 12px;
      white-space: nowrap;
    }

    .popularity-icon {
      font-size: 14px;
    }

    .popularity-filter-selector :deep(.ant-radio-button-wrapper::before) {
      display: none;
    }

    .popularity-filter-selector :deep(.ant-radio-button-wrapper:hover) {
      border-color: var(--theme-error);
      color: var(--theme-error);
      transform: translateY(-2px);
      box-shadow: 0 4px 12px var(--theme-shadow);
      z-index: 2;
    }

    .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked) {
      background: linear-gradient(135deg, var(--theme-error) 0%, var(--theme-warning) 100%);
      border-color: var(--theme-error);
      color: var(--theme-surface);
      box-shadow: 0 6px 20px var(--theme-shadow);
      transform: translateY(-2px);
      z-index: 3;
    }

    .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked:hover) {
      background: linear-gradient(135deg, var(--theme-warning) 0%, var(--theme-info) 100%);
      border-color: var(--theme-warning);
      box-shadow: 0 8px 25px var(--theme-shadow);
    }

    .popularity-filter-selector :deep(.ant-radio-button-wrapper-checked::after) {
      display: none;
    }

  .page-type-content {
    width: 100%;
    justify-content: center;
  }

  .page-type-wrapper {
    max-width: none;
    padding: 0;
  }

  .page-type-hint {
    padding: 10px 16px;
    font-size: 13px;
  }

  .hint-icon {
    font-size: 16px;
  }

  .page-type-selector {
    flex-direction: row;
    gap: 0;
    width: 100%;
    justify-content: center;
  }

  .page-type-selector :deep(.ant-radio-button-wrapper) {
    width: auto;
    height: 44px;
    justify-content: center;
    border-radius: 0;
    flex: 1;
    max-width: none;
    font-size: 13px;
    padding: 0 16px;
  }

  .button-icon {
    font-size: 16px;
  }

  .page-type-selector :deep(.ant-radio-button-wrapper::before) {
    display: none;
  }

      .page-type-selector :deep(.ant-radio-button-wrapper:hover) {
      border-color: var(--theme-primary);
      color: var(--theme-primary);
      transform: translateY(-2px);
      box-shadow: 0 4px 12px var(--theme-shadow);
      z-index: 2;
    }

      .page-type-selector :deep(.ant-radio-button-wrapper-checked) {
      background: linear-gradient(135deg, var(--theme-primary) 0%, var(--theme-secondary) 100%);
      border-color: var(--theme-primary);
      color: var(--theme-surface);
      box-shadow: 0 6px 20px var(--theme-shadow);
      transform: translateY(-2px);
      z-index: 3;
    }

      .page-type-selector :deep(.ant-radio-button-wrapper-checked:hover) {
      background: linear-gradient(135deg, var(--theme-secondary) 0%, var(--theme-info) 100%);
      border-color: var(--theme-secondary);
      box-shadow: 0 8px 25px var(--theme-shadow);
    }

  .page-type-selector :deep(.ant-radio-button-wrapper-checked::after) {
    display: none;
  }

  /* 移动端loading指示器样式 */
  .page-type-loading {
    margin-top: 16px;
    padding: 10px 20px;
  }

  .loading-text {
    font-size: 13px;
  }

  .operation-bar {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }

  .search-area {
    width: 100%;
  }

  .search-area .ant-input-search {
    width: 100% !important;
  }

  .action-area {
    display: flex;
    gap: 8px;
  }

  .action-area .ant-space {
    width: 100%;
    justify-content: space-between;
  }

  .action-area .ant-btn {
    flex: 1;
  }

  .grid-view {
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
    padding: 12px;
  }

  .hot-recommend-section {
    padding: 16px;
    margin-bottom: 16px;
  }

  .section-title {
    font-size: 20px;
  }

  .hot-recommend-list {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
  }
}

@media (max-width: 480px) {
  .home-container {
    padding: 12px;
  }

  .filter-section {
    gap: 12px;
  }

  .page-type-selector :deep(.ant-radio-button-wrapper) {
    height: 40px;
    font-size: 12px;
    padding: 0 12px;
  }

  .page-type-selector :deep(.ant-radio-button-wrapper:first-child) {
    border-radius: 20px 0 0 20px;
  }

  .page-type-selector :deep(.ant-radio-button-wrapper:last-child) {
    border-radius: 0 20px 20px 0;
  }

  .grid-view {
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 8px;
    padding: 8px;
  }

  .hot-recommend-list {
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 8px;
  }
}

/* 页面类型切换loading指示器样式 */
  .page-type-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 12px;
    padding: 8px 16px;
    background: linear-gradient(135deg, var(--theme-background) 0%, var(--theme-surface) 100%);
    border-radius: 20px;
    border: 1px solid var(--theme-border);
    animation: loadingSlideIn 0.3s ease-out;
    transition: all 0.3s ease;
  }

  .loading-text {
    color: var(--theme-primary);
    font-size: 14px;
    font-weight: 500;
    transition: color 0.3s ease;
  }

@keyframes loadingSlideIn {
  0% {
    opacity: 0;
    transform: translateY(-10px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 内容区域动画样式 */
.content-section {
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  will-change: opacity, transform, filter, box-shadow;
  position: relative;
  transform-style: preserve-3d; /* 保持3D变换 */
}

  .content-section.loading {
    opacity: 0.4;
    transform: scale(0.96) rotateX(2deg);
    filter: blur(1px) brightness(0.9);
    box-shadow: 0 20px 40px var(--theme-shadow);
  }

  .content-section.loaded {
    opacity: 1;
    transform: scale(1) rotateX(0deg);
    filter: blur(0px) brightness(1);
    box-shadow: 0 4px 12px var(--theme-shadow);
  }

/* 确保loading状态下的文字和图标显示在最上层 */
.content-section .ant-spin,
.content-section .ant-spin-dot,
.content-section .ant-spin-text {
  z-index: 9999 !important; /* 使用更高的z-index确保在最上层 */
  position: relative;
}

/* 确保loading文字不受父元素透明度影响，始终清晰显示 */
.content-section .ant-spin-text {
  opacity: 1 !important;
  color: #1890ff !important;
  font-weight: 600 !important; /* 加粗字体，更清晰 */
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8) !important; /* 添加白色阴影，增强可读性 */
  background: rgba(255, 255, 255, 0.9) !important; /* 添加半透明背景 */
  padding: 4px 8px !important; /* 添加内边距 */
  border-radius: 4px !important; /* 圆角背景 */
  backdrop-filter: blur(0px) !important; /* 确保不被模糊 */
}

/* 确保loading图标也不受模糊影响 */
.content-section .ant-spin-dot {
  filter: none !important; /* 移除任何滤镜效果 */
  backdrop-filter: none !important; /* 移除背景模糊 */
}

/* 确保整个loading容器不受父元素影响 */
.content-section .ant-spin {
  filter: none !important;
  backdrop-filter: none !important;
  transform: none !important; /* 不受父元素的变换影响 */
}

/* 添加页面类型选择器的增强动画效果 */
.page-type-selector :deep(.ant-radio-button-wrapper) {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

/* 添加悬停时的3D效果 - 减少抖动 */
  .page-type-selector :deep(.ant-radio-button-wrapper:hover) {
    transform: translateY(-1px) scale(1.01); /* 减少移动和缩放幅度 */
    box-shadow: 0 6px 16px var(--theme-shadow);
  }

/* 选中状态的增强效果 - 减少抖动 */
  .page-type-selector :deep(.ant-radio-button-wrapper-checked) {
    animation: selectedPulse 0.6s ease-out;
    box-shadow: 0 6px 20px var(--theme-shadow);
  }

@keyframes selectedPulse {
  0% {
    transform: scale(1);
    box-shadow: 0 4px 12px var(--theme-shadow);
  }
  50% {
    transform: scale(1.03); /* 减少放大幅度 */
    box-shadow: 0 8px 24px var(--theme-shadow);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 6px 20px var(--theme-shadow);
  }
}

/* 图标动画增强 - 减少抖动 */
.page-type-selector :deep(.ant-radio-button-wrapper-checked) .button-icon {
  animation: iconBounce 0.8s ease-out;

}

@keyframes iconBounce {
  0%,
  20%,
  53%,
  80%,
  100% {
    transform: translate3d(0, 0, 0);
  }
  40%,
  43% {
    transform: translate3d(0, -4px, 0); /* 减少弹跳高度 */
  }
  70% {
    transform: translate3d(0, -2px, 0); /* 减少弹跳高度 */
  }
  90% {
    transform: translate3d(0, -1px, 0); /* 减少弹跳高度 */
  }
}

  /* 列表模式操作按钮样式 */
  .list-view .ant-table-tbody .ant-btn-text.icon-only-btn {
    padding: 4px;
    height: 28px;
    width: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
  }

  .list-view .ant-table-tbody .ant-btn-text.icon-only-btn:hover {
    background: var(--theme-background);
    transform: scale(1.1);
  }

  .list-view .ant-table-tbody .ant-btn-text.icon-only-btn .anticon {
    font-size: 16px;
  }

  .list-view .ant-table-tbody .ant-space {
    gap: 8px;
  }
</style>
